﻿using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using OpenAdmin.Core.Consts;
using OpenAdmin.Core.DbContextLocators;
using OpenAdmin.Core.Models;

namespace OpenAdmin.EntityFramework;

[AgilityDbContext("Default", $"{DatabaseProvider.MySql}@8.0.30")]
public class ApplicationDbContext : AgilityDbContext<ApplicationDbContext, ApplicationDbContextLocator>, IMultiTenancyOnTable, IEntityTypeBuilderFilter
{
    public DbSet<SysUser> SysUsers { get; set; }

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
    {

    }
    public void OnCreating(EntityTypeBuilder entityTypeBuilder, DbContext dbContext)
    {

    }

    public void OnCreated(EntityTypeBuilder entityTypeBuilder, DbContext dbContext)
    {

    }

    protected override void SavingChangesEvent(DbContextEventData eventData, InterceptionResult<int> result)
    {
        // 获取当前事件对应上下文
        var dbContext = eventData.Context;

        // 获取所有新增、更新、删除的实体
        var entities = dbContext.ChangeTracker.Entries().Where(u => u.State == EntityState.Added || u.State == EntityState.Modified || u.State == EntityState.Deleted);

        var currentUserId = App.HttpContext?.User?.FindFirst(ClaimTypeConsts.UserId)?.Value;
        foreach (var entity in entities)
        {
            switch (entity.State)
            {
                case EntityState.Added:
                    // 自动设置租户Id
                    if (entity.Properties.Any(p => p.Metadata.Name == nameof(TenantEntity.TenantId)))
                    {
                        var tenantId = entity.Property(nameof(TenantEntity.TenantId)).CurrentValue;
                        if (!Guid.TryParse(tenantId?.ToString(), out var guidTenantId) || guidTenantId == Guid.Empty)
                        {
                            entity.Property(nameof(TenantEntity.TenantId)).CurrentValue = CurrentTenantId;
                        }
                    }
                    //自己设置创建人
                    if (entity.Properties.Any(p => p.Metadata.Name == nameof(Entity.CreateBy)))
                    {
                        if (!string.IsNullOrWhiteSpace(currentUserId))
                        {
                            entity.Property(nameof(Entity.CreateBy)).CurrentValue = Convert.ToInt32(currentUserId);
                        }
                    }
                    break;
                case EntityState.Modified:
                    // 排除租户Id
                    if (entity.Properties.Any(p => p.Metadata.Name == nameof(TenantEntity.TenantId)))
                    {
                        entity.Property(nameof(TenantEntity.TenantId)).IsModified = false;
                    }
                    //自动修改记录更新时间
                    if (entity.Properties.Any(p => p.Metadata.Name == nameof(Entity.ModifyTime)))
                    {
                        entity.Property(nameof(Entity.ModifyTime)).CurrentValue = DateTime.Now;
                    }
                    break;
                // 删除处理
                case EntityState.Deleted:
                    break;
            }
        }
    }

    public object GetCurrentTenantId()
    {
        return base.CurrentTenant?.TenantId;
    }
}
